/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
 * Description: white list module for driver
 * Author:  huawei
 * Create:  2019-10-21
 */
#ifndef _DRV_WHITELIST_H
#define _DRV_WHITELIST_H

#include "drv_log.h"

#ifdef STATIC_SKIP
#define STATIC
#else
#define STATIC static
#endif

/* error code */
#define WL_OK 0
#define WL_ERR_PARA (-1)
#define WL_ERR_SHA256_CHECK (-2)
#define WL_ERR_MEM_ALLOC (-3)
#define WL_ERR_MEM_CMP (-4)
#define WL_ERR_MEM_CPY (-5)
#define WL_ERR_NO_AUTHORITY (-6)
#define WL_ERR_FILE_OPEN (-7)
#define WL_ERR_FILE_READ (-8)
#define WL_ERR_FILE_FORMAT (-9)
#define WL_ERR_MEM_INIT (-10)
#define WL_ERR_SOC_VERIFY (-11)

/* log */
#define WL_LOG_PREFIX "whitelist"

#define WHITELIST_ERR(fmt, ...)                                                              \
    do {                                                                                     \
        drv_err(WL_LOG_PREFIX, "<%s:%d> " fmt, current->comm, current->tgid, ##__VA_ARGS__); \
    } while (0);
#define WHITELIST_WARN(fmt, ...)                                                              \
    do {                                                                                      \
        drv_warn(WL_LOG_PREFIX, "<%s:%d> " fmt, current->comm, current->tgid, ##__VA_ARGS__); \
    } while (0);
#define WHITELIST_INFO(fmt, ...)                                                              \
    do {                                                                                      \
        drv_info(WL_LOG_PREFIX, "<%s:%d> " fmt, current->comm, current->tgid, ##__VA_ARGS__); \
    } while (0);

/* process white list */
#define PROCESS_LIST_FILE_MAX 0x100000 /* 1M Byte max */
#define PROCESS_LIST_FILE_PATH "/var/process.list"
#define PROCESS_LIST_SHA256_BYTES 64
#define PROCESS_EXCUTABLE_FLAG 0x75
#define SHA256_BYTE_STR_LEN 3
#define PROCESS_TEXT_OFFSET_HEX 16
#define BUF_OFFSET_3BYTES 3
#define BUF_OFFSET_2BYTES 2
#define WL_SHA256_DIGEST 32
#define WL_DATA_NUM_EVEN 2
#define WL_TEXT_OFFSET_BYTES_MAX 10
#define WL_NAME_NUM_MAX 50

#define WL_IS_FOUND 1
#define WL_IS_NOT_FOUND 0

#define SOC_HEAD_SIZE 0x4000
#define NVCNT_INFO_SIZE 0

/* process list info, including process dependent so and bin file */
typedef struct _process_list_info {
    u8 *file_path;       /* file path */
    u32 file_path_len;   /* file path length */
    u8 *text_offset;     /* text segment offset end */
    u32 text_offset_len; /* text offset length */
    u8 *check_code;      /* sha256 check code, 64Bytes */
} process_info_t;

/* process list file record */
typedef struct _process_file {
    u8 *list_file;
    loff_t file_len;
    struct list_head process_list;
} process_file_t;

/* file parse info */
typedef struct _file_parse_info {
    u8 *file_path;
    u32 file_path_len;                /* file path length */
    u8 *text_offset_ascii;            /* text segment offset data */
    u32 text_offset_len;              /* text offset length */
    u32 act_text_offset;              /* actual text section offset */
    u8 *check_code;                   /* sha256 check code, 64Bytes */
    u8 sha256_code[WL_SHA256_DIGEST]; /* actual sha256 check code */
    struct list_head file_list;
} file_parse_info_t;

/* process parse info */
typedef struct _process_parse_info {
    u8 *process_name;
    u32 process_name_len;
    u8 *start_pos;
    u32 content_size;
    struct list_head file_list;
    struct list_head process_list;
} process_parse_info_t;

/*
 * desc: Driver process whitelist check handler
 * in:   const char **list name   the process whitelist name pointer
 * u32 name_num  whitelist name num
 * ret:  0: check success   others: failed
 */
s32 whitelist_process_handler(const char **list_name, u32 name_num);

/*
 * desc: read process.list file and point to a global pointer
 * ret:  0: check success   others: failed
 */
s32 whitelist_read_process_list_file(void);

/*
 * desc: free process_list_file when ko rmmod
 */
void whitelist_free_process_list_file(void);

/*
 * get current process name and name size
 */
s32 whitelist_get_cur_process_name(u8 **p_file_name, u32 *name_size);

#endif
